home *** CD-ROM | disk | FTP | other *** search
/ Chip 2006 June (Extra) / CHIP 2006-06.3.iso / program / opensource / clamav-devel.exe / contrib / optimize / optimize.c
Encoding:
C/C++ Source or Header  |  2006-05-16  |  4.2 KB  |  212 lines

  1. /*
  2.  *  Copyright (C) 2004 Tomasz Kojm <tkojm@clamav.net>
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  17.  *  MA 02110-1301, USA.
  18.  */
  19.  
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23. #include <stdlib.h>
  24.  
  25. #define MINLENGTH 40 /* only optimize signatures longer than MINLENGT */
  26. #define FILEBUFF 16384
  27. #define ANALYZE 6 /* only analyze first ANALYZE characters */
  28.  
  29. int hex2int(int c)
  30. {
  31.     int l = tolower(c);
  32.  
  33.     if (!isascii(l))
  34.         return -1;
  35.     if (isdigit(l))
  36.     return l - '0';
  37.     if ((l >= 'a') && (l <= 'f'))
  38.     return l + 10 - 'a';
  39.  
  40.     return -1;
  41. }
  42.  
  43. char *hex2str(const char *hex, int howmany)
  44. {
  45.     short int val, c;
  46.     int i, len;
  47.     char *str, *ptr;
  48.  
  49.     len = strlen(hex);
  50.  
  51.     /* additional check - hex strings are parity length here */
  52.     if(len % 2 != 0) {
  53.     printf("hex2str(): Malformed hexstring: %s (length: %d)\n", hex, len);
  54.     return NULL;
  55.     }
  56.  
  57.     str = calloc((howmany / 2) + 1, sizeof(char));
  58.     if(!str)
  59.     return NULL;
  60.  
  61.     ptr = str;
  62.  
  63.     if(howmany > len)
  64.     howmany = len;
  65.  
  66.     for(i = 0; i < howmany; i += 2) {
  67.     if(hex[i] == '?') {
  68.         printf("Can't optimize polymorphic signature.\n");
  69.         free(str);
  70.         return NULL;
  71.     } else {
  72.         if((c = hex2int(hex[i])) >= 0) {
  73.         val = c;
  74.         if((c = hex2int(hex[i+1])) >= 0) {
  75.             val = (val << 4) + c;
  76.         } else { 
  77.             free(str);
  78.             return NULL;
  79.         }
  80.         } else {
  81.         free(str);
  82.         return NULL;
  83.         }
  84.     }
  85.     *ptr++ = val;
  86.     }
  87.  
  88.     return str;
  89. }
  90.  
  91. void chomp(char *string)
  92. {
  93.     size_t l = strlen(string);
  94.  
  95.     if(l == 0)
  96.     return;
  97.  
  98.     --l;
  99.     if((string[l] == '\n') || (string[l] == '\r')) {
  100.     string[l] = '\0';
  101.  
  102.     if(l > 0) {
  103.         --l;
  104.         if(string[l] == '\r')
  105.         string[l] = '\0';
  106.     }
  107.     }
  108. }
  109.  
  110. int main(int argc, char **argv)
  111. {
  112.     int line = 0, found, i, nodes = 0, optimized = 0, optimal = 0;
  113.     unsigned char c1, c2;
  114.     char *buffer, *start, *pt, **prefix, *sig;
  115.     FILE *in, *out;
  116.  
  117.  
  118.     if(argc != 3) {
  119.     printf("%s input_db output_db\n", argv[0]);
  120.     exit(1);
  121.     }
  122.  
  123.     if((in = fopen(argv[1], "rb")) == NULL) {
  124.     printf("Can't open input database %s\n", argv[1]);
  125.     exit(1);
  126.     }
  127.  
  128.     if((out = fopen(argv[2], "wb")) == NULL) {
  129.     printf("Can't open output database %s\n", argv[1]);
  130.     exit(1);
  131.     }
  132.  
  133.     prefix = (char **) calloc(256, sizeof(char *));
  134.     for(i = 0; i < 256; i++)
  135.     prefix[i] = (char *) calloc(256, sizeof(char));
  136.  
  137.     if(!(buffer = (char *) malloc(FILEBUFF))) {
  138.     exit(1);
  139.     }
  140.  
  141.     memset(buffer, 0, FILEBUFF);
  142.  
  143.     while(fgets(buffer, FILEBUFF, in)) {
  144.  
  145.     line++;
  146.     chomp(buffer);
  147.  
  148.     pt = strchr(buffer, '=');
  149.     if(!pt) {
  150.         printf("Malformed pattern line %d.\n", line);
  151.         free(buffer);
  152.         exit(1);
  153.     }
  154.  
  155.     start = buffer;
  156.     *pt++ = 0;
  157.  
  158.     if(*pt == '=')
  159.         continue;
  160.  
  161.     if(strlen(pt) < MINLENGTH) {
  162.         fprintf(out, "%s=%s\n", start, pt);
  163.         continue;
  164.     }
  165.  
  166.     sig = hex2str(pt, 2 * ANALYZE);
  167.  
  168.     if(!sig) {
  169.         printf("Can't decode signature %d\n", line);
  170.         exit(1);
  171.     }
  172.  
  173.     found = -1;
  174.  
  175.     for(i = 0; i < ANALYZE - 1; i++) {
  176.         c1 = ((unsigned char) sig[i]) & 0xff;
  177.         c2 = ((unsigned char) sig[i + 1]) & 0xff;
  178.  
  179.         if(prefix[c1][c2]) {
  180.         found = i;
  181.         break;
  182.         }
  183.     }
  184.  
  185.     if(found < 0) {
  186.         printf("Can't optimize signature %d\n", line);
  187.         prefix[c1][c2] = 1;
  188.         nodes++;
  189.     } else if(found == 0) {
  190.         printf("Signature %d is already optimal.\n", line);
  191.         optimal++;
  192.     } else {
  193.         pt = pt + 2 * found;
  194.         printf("Signature %d optimized (new start at %d byte)\n", line, found);
  195.         optimized++;
  196.     }
  197.  
  198.     fprintf(out, "%s=%s\n", start, pt);
  199.     }
  200.  
  201.     fclose(in);
  202.     fclose(out);
  203.  
  204.     free(buffer);
  205.     for(i = 0; i < 256; i++)
  206.     free(prefix[i]);
  207.     free(prefix);
  208.  
  209.     printf("Nodes: %d, Optimal: %d, Signatures optimized: %d\n", nodes, optimal, optimized);
  210.     exit(0);
  211. }
  212.